package com.etoak.service.impl;

import cn.hutool.crypto.digest.MD5;
import com.etoak.common.constant.CommonConstant;
import com.etoak.common.jwt.JwtUtil;
import com.etoak.common.web.exception.CustomException;
import com.etoak.dto.LoginDTO;
import com.etoak.entity.User;
import com.etoak.mapper.UserMapper;
import com.etoak.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etoak.vo.TokenVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author et2403
 * @since 2024-08-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    StringRedisTemplate redisTemplate;

    public TokenVO login(LoginDTO loginDTO) {
        // 获取Redis中存储的验证码
        String code = redisTemplate.opsForValue().get(CommonConstant.REDSI_CODE_PREFIX + loginDTO.getUuid());
        // 如果验证码为空或者与传入的验证码不匹配，抛出异常
        if (StringUtils.isEmpty(code) || !StringUtils.equals(code, loginDTO.getCode())) {
            throw new CustomException("验证码错误或失效！");
        }
        // 使用LambdaQuery查询用户信息，条件是用户名和密码（密码经过MD5加密后比较）
        User user = lambdaQuery().eq(User::getUsername, loginDTO.getUsername())
                .eq(User::getPassword, MD5.create().digestHex(loginDTO.getPassword())).one();
        // 如果查询结果为空，说明用户名或密码错误，抛出异常
        if (ObjectUtils.isEmpty(user)) {
            throw new CustomException("用户名或密码错误！");
        }
        // 创建一个HashMap用于存储JWT的载荷信息
        Map<String, Object> map = new HashMap<>();
        // 将用户ID和用户名放入HashMap中
        map.put("id", user.getId());
        map.put("username", user.getUsername());
        // 使用JwtUtil工具类生成JWT令牌
        String token = JwtUtil.create(map);
        // 创建TokenVO对象并返回，包含用户名和生成的JWT令牌
        return new TokenVO(user.getUsername(), token);
    }
}
